//package com.woniuxy.info.gateway.config;
//
//import com.fasterxml.jackson.databind.ObjectMapper;
//import com.woniuxy.sddfp.common.constant.RedisConstant;
//import com.woniuxy.sddfp.common.constant.UserConstant;
//import com.woniuxy.sddfp.common.exception.BusinessException;
//import com.woniuxy.sddfp.common.result.Result;
//import com.woniuxy.sddfp.common.result.enums.IErrorCode;
//import com.woniuxy.sddfp.common.result.enums.impl.BusinessCode;
//import com.woniuxy.sddfp.common.util.JwtTemplate;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.cloud.gateway.filter.GatewayFilterChain;
//import org.springframework.cloud.gateway.filter.GlobalFilter;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.core.io.buffer.DataBuffer;
//import org.springframework.data.redis.core.StringRedisTemplate;
//import org.springframework.http.server.reactive.ServerHttpRequest;
//import org.springframework.http.server.reactive.ServerHttpResponse;
//import org.springframework.util.AntPathMatcher;
//import org.springframework.util.StringUtils;
//import org.springframework.web.server.ServerWebExchange;
//import reactor.core.publisher.Mono;
//
//import java.time.Duration;
//import java.util.List;
//
///**
// * 统一网关全局过滤器
// * 鉴权、拦截所有请求
// * 全局过滤器：实现GlobalFilter
// */
//@Configuration
//public class AuthFilter implements GlobalFilter {
//    //放行配置名单
//    @Autowired
//    private IgnorePathConfig ignorePathConfig;
//    //redis工具类
//    @Autowired
//    private StringRedisTemplate stringRedisTemplate;
//    /**
//     * token工具类自定义
//     */
//    @Autowired
//    private JwtTemplate jwtTemplate;
//
//    public static final String AUTHORIZATION = "Authorization";
//    public static final String BEARER = "Bearer ";
//
//    @Override
//    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//        ServerHttpRequest request = exchange.getRequest();
//        ServerHttpResponse response = exchange.getResponse();
//        //1、获取请求路径放行白名单资源
//        String path = request.getURI().getPath();
//        List<String> whiteList = ignorePathConfig.getWhiteList();
//        AntPathMatcher pathMatcher = new AntPathMatcher();
//
//
//        //方式2//判断是否在白名单中match(匹配模式集合,实际请求路径)
//        boolean flag = whiteList.stream().anyMatch(urlPattern -> pathMatcher.match(urlPattern, path));
//        if (flag){
//            return chain.filter(exchange);
//        }
//
//        //2.获取请求头, 得到token
//        String authToken = request.getHeaders().getFirst(AUTHORIZATION);
//        if (StringUtils.isEmpty(authToken)){
//            //返回错误
//            return responseError(response, BusinessCode.TOKEN_ISNULL);
//        }
//        //去掉前缀"Bearer ",
//        authToken = authToken.replace(BEARER, "");
//
//        //3、校验token
//        if (!jwtTemplate.verifyToken(authToken)){
//            return responseError(response, BusinessCode.TOKEN_INVALID);
//        }
//        //4、解析token,获取userId,校验是否过期
//        String userId = jwtTemplate.parseToken(authToken, UserConstant.TOKEN_USERID).toString();
//        String key = RedisConstant.USER_TOKEN_PREFIX + userId;
//        if (!stringRedisTemplate.hasKey(key)){
//            return responseError(response, BusinessCode.TOKEN_EXPIRED);
//        }
//
//        //5、续期
//        stringRedisTemplate.expire(key, Duration.ofMinutes(30));
//        //6网关重写请求头，让请求头携带userId，再转发微服务,其他微服务就可以获取
//        request.mutate().header(UserConstant.TOKEN_USERID,userId);
//        //7.微服务直接从请求头获取id request.getHeader("userId")
//        return chain.filter(exchange);
//    }
//
//    /**
//     * 网关校验token错误公用方法
//     */
//    private Mono<Void> responseError(ServerHttpResponse response, IErrorCode errorCode) {
//        try {
//            Result result = Result.fail(errorCode);
//            byte[] bytes = new ObjectMapper().writeValueAsBytes(result);
//            DataBuffer dataBuffer = response.bufferFactory().wrap(bytes);
//            return response.writeWith(Mono.just(dataBuffer));
//        } catch (Exception e) {
//            throw new BusinessException(BusinessCode.NO_AUTH);
//        }
//    }
//}
